<template>
  <div
    class="bl-banner"
    :style="{ height: bannerHeight, backgroundImage: backgroundImageStyle }"
  >
    <div class="banner-content">
      <h1>{{ title }}</h1>
      <h3 ref="subtitleRef" class="typewriter">{{ displayedSubtitle }}</h3>
    </div>
    <div class="wave">
      <svg width="100%" height="60" viewBox="0 0 1440 60">
        <path fill="#f5f5f5" d="..."/>
      </svg>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, computed } from "vue";

const props = defineProps({
  title: { type: String, required: true },
  subtitle: { type: String, required: true },
  bannerHeight: { type: String, default: "55vh" },
  backgroundImage: { type: String, default: "" },
  typeSpeed: { type: Number, default: 100 }, // ms/字
});

const displayedSubtitle = ref("");
const subtitleRef = ref(null);

function startTypewriter() {
  displayedSubtitle.value = "";
  let i = 0;
  function type() {
    if (i <= props.subtitle.length) {
      displayedSubtitle.value = props.subtitle.slice(0, i);
      i++;
      setTimeout(type, props.typeSpeed);
    }
  }
  type();
}

watch(() => props.subtitle, startTypewriter, { immediate: true });

const backgroundImageStyle = computed(() => {
  if (!props.backgroundImage) return "";
  // 如果是以 / 开头，直接用
  if (props.backgroundImage.startsWith("/")) {
    return `url('${props.backgroundImage}')`;
  }
  // 如果是 @ 开头，使用 new URL 解析
  if (props.backgroundImage.startsWith("@/")) {
    // vite 环境
    try {
      console.log(
        `url('${
          new URL(props.backgroundImage.replace("@", "../.."), import.meta.url)
            .href
        }')`
      );
      return `url('${
        new URL(props.backgroundImage.replace("@", "../.."), import.meta.url)
          .href
      }')`;
    } catch {
      return "";
    }
  }
  // 其他情况直接用
  return `url('${props.backgroundImage}')`;
});

onMounted(() => {
  if (window.CSS && CSS.paintWorklet) {
    const moduleUrl = new URL("@/utils/CSSHoudini.js", import.meta.url).href;
    CSS.paintWorklet.addModule(moduleUrl);
  }
});
</script>

<style scoped lang="less">
.bl-banner {
  width: 100%;
  position: relative;
  background: @color2;
  background-repeat: no-repeat;
  background-size: cover;
  background-origin: center;
  background-position: center;

  .banner-content {
    position: absolute;
    top: 30%;
    left: 50%;
    transform: translateX(-50%);
    width: 30%;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 30px;

    h1 {
      color: @white;
      text-align: center;
    }

    .typewriter {
      margin-top: 20px;
      color: @white;
      background: @black-alpha-2;
      padding: 10px;
      border-radius: 8px;
      box-sizing: border-box;
      margin: 0 auto;
      overflow: hidden;
      white-space: nowrap;
      position: relative;
      min-height: 24px;
      padding-right: 20px;
    }

    .typewriter::after {
      content: "";
      display: inline-block;
      width: 2px;
      height: 1em;
      background: @color1;
      vertical-align: middle;
      margin-left: 5px;
      animation: blink-caret 0.7s steps(1) infinite;
      position: absolute;
      right: 10px;
      top: 50%;
      transform: translateY(-50%);
      pointer-events: none;
    }
  }

  .wave {
    position: absolute;
    bottom: 0;
    width: 100%;
    height: 300px;
    background: paint(waveDraw);
    animation: move 20s infinite linear;
    --amplitude: 20;
    --gap: 40;
    --animation-tick: 700;
    --height: 0.7;
    --color1: @color1;
    --color2: @color2;
    transition: --height 8s;
  }
}

@property --animation-tick {
  syntax: "<number>";
  inherits: false;
  initial-value: 1000;
}

@keyframes move {
  100% {
    --animation-tick: 1;
  }
}

@keyframes blink-caret {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}
</style>
